package org.akomantoso.core.io.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.Background;
import org.akomantoso.core.data.Decision;
import org.akomantoso.core.data.Introduction;
import org.akomantoso.core.data.JudgementBlock;
import org.akomantoso.core.data.Motivation;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;

/**
 * 
 * @author <a href="mailto:jacques.militello@gmail.com">Jacques Militello</a>
 * 
 */
public final class JudgementBlockUtil {

	private JudgementBlockUtil() {
	}

	static final Map<String, Instantiator<JudgementBlock>> MAP = new HashMap<String, Instantiator<JudgementBlock>>();

	
	public static void read(Input in,List<JudgementBlock> blocks) throws IOException {
		JudgementBlock block = null;
		final String localName = in.getLocalName();
		
		while(true) {
			in.readNext();
			switch (in.getEventType()) {
			case InputConstants.START_ELEMENT:
				block = instantiate(in.getLocalName());
				block.readExternal(in);
				blocks.add(block);
				break;			
			case InputConstants.END_ELEMENT:
				if (localName.equals(in.getLocalName())) {
					return;
				} 
			}
		}
	}
	
	private static JudgementBlock instantiate(String element) {
		final Instantiator<? extends JudgementBlock> instatiator = MAP.get(element);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + element + "] not supported JudgementBlock ?!?");
		}
		return instatiator.instantiate();
	}
	
	static {

		// introduction
		MAP.put(Introduction.ELEMENT, new Instantiator<JudgementBlock>() {
			public JudgementBlock instantiate() {
				return new Introduction();
			}
		});

		// background;
		MAP.put(Background.ELEMENT, new Instantiator<JudgementBlock>() {
			public JudgementBlock instantiate() {
				return new Background();
			}
		});

		// motivation;
		MAP.put(Motivation.ELEMENT, new Instantiator<JudgementBlock>() {
			public JudgementBlock instantiate() {
				return new Motivation();
			}
		});

		// decision;
		MAP.put(Decision.ELEMENT, new Instantiator<JudgementBlock>() {
			public JudgementBlock instantiate() {
				return new Decision();
			}
		});

	}

}